/*
 * @Description: 
 * @Author: duan_shuangjun 丶
 * @Date: 2025-08-20 20:36:56
 * @LastEditTime: 2025-09-30 11:03:48
 */
import axios, { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import { LocalStorage } from '@/utils/storage'
import { useUserStore } from '@/stores/user'
import type { ApiResponse } from '@/types/http'

// baseURL 优先级：window.__API_BASE_URL__ > 环境变量 > '/'
// 允许通过全局变量在本地覆盖
const runtimeBase = (window as any).__API_BASE_URL__
const baseURL: string = runtimeBase || import.meta.env.VITE_API_BASE_URL || '/'

// 全局loading状态管理
let loadingInstance: any = null
let requestCount = 0

// 显示loading 
const showLoading = () => {
    if (requestCount === 0) {
        loadingInstance = ElLoading.service({
            lock: true,
            text: '加载中...',
            background: 'rgba(0, 0, 0, 0.7)'
        })
    }
    requestCount++
}

// 隐藏loading
const hideLoading = () => {
    requestCount--
    if (requestCount <= 0) {
        requestCount = 0
        if (loadingInstance) {
            loadingInstance.close()
            loadingInstance = null
        }
    }
}

const http: AxiosInstance = axios.create({
    baseURL,
    timeout: 5 * 60 * 1000,
    headers: { 'Content-Type': 'application/json;charset=utf-8' }
})

http.interceptors.request.use((config: InternalAxiosRequestConfig) => {
    const token = LocalStorage.get('token')
    if (token) {
        (config.headers as any)['Access-Token'] = token
    }

    // 显示loading，排除某些不需要loading的请求
    // const noLoading = (config as any).noLoading
    // if (!noLoading) {
    //     showLoading()
    // }

    return config
})

http.interceptors.response.use(
    (res: AxiosResponse<ApiResponse>) => {
        try { useUserStore().setNetworkStatus('online') } catch { }
        const code = (res.data as any)?.status ?? 200
        const message = (res.data as any)?.message || (res.data as any)?.msg || '系统升级中'

        // 隐藏loading
        // const noLoading = (res.config as any).noLoading
        // if (!noLoading) {
        //     hideLoading()
        // }

        if (res.request?.responseType === 'blob' || res.request?.responseType === 'arraybuffer') {
            return res.data as any
        }

        if (code === 401) {
            console.log('检测到401状态码，准备跳转登录页面')

            // 清除token
            try {
                useUserStore().setToken('')
                LocalStorage.remove('token')
            } catch { }

            // 显示错误提示
            ElMessage.error('登录状态已过期，请重新登录')

            // 延迟跳转，让用户看到提示
            setTimeout(() => {
                window.location.hash = '/login'
            }, 500)

            // 返回Promise.reject，这样调用方会进入catch块
            return Promise.reject(new Error('登录状态已过期，请重新登录'))
        }
        if (code === 500) {
            ElMessage.error(message)
            return res.data as any
        }
        if (code !== 200) {
            ElMessage.error(message)
            return res.data as any
        }
        return res.data as any
    },
    (error) => {
        try { useUserStore().setNetworkStatus('offline') } catch { }

        // 隐藏loading
        // const noLoading = (error.config as any)?.noLoading
        // if (!noLoading) {
        //     // hideLoading()
        // }

        let { message } = error
        if (message === 'Network Error') {
            console.warn('网络异常，请检查连接')
        } else if (message?.includes('timeout')) {
            ElMessage.error('系统接口请求超时')
        } else if (message?.includes('Request failed with status code')) {
            ElMessage.error('系统接口' + message.substr(message.length - 3) + '异常')
        }
        return Promise.reject(error)
    }
)

export default http
// 导出loading控制函数，供其他模块使用
export const httpLoading = {
    show: showLoading,
    hide: hideLoading
}

/*
使用示例：

1. 默认所有请求都会显示loading
const res = await http.get('/api/users')

2. 如果某个请求不需要loading，可以设置noLoading选项
const res = await http.get('/api/users', { noLoading: true })

3. 手动控制loading状态
import { httpLoading } from '@/utils/http'
httpLoading.show()  // 显示loading
httpLoading.hide()  // 隐藏loading
*/

